package org.zizi.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;
import org.zizi.convert.Converter;

public class Options
{
	private static final Logger log = Logger.getLogger(Options.class);
	
	////////////////////////
	
	private static Options instance;
	
	public static Options get()
	{
		return instance;
	}
	
	////////////////////////
	
	private Map<String, String> options = new HashMap<String, String>();
	
	public Options()
	{
		instance = this;
	}
	
	public void load(File file) throws Exception
	{
		if (!file.exists()) return;
		
		log.info("载入系统配置...");
		
		LineNumberReader reader = null;
		try
		{
			reader = new LineNumberReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
			load(reader);
		}
		catch (Exception e)
		{
			throw new Exception("载入系统配置错误", e);
		}
		finally
		{
			Closer.close(reader);
		}
	}
	
	private void load(LineNumberReader reader) throws Exception
	{
		for (;;)
		{
			String s = reader.readLine();
			if (s == null) break;

			s = s.trim();

			if (s.isEmpty()) continue;
			if (s.startsWith("#")) continue;

			// key
			int k = s.indexOf("=");
			if (k < 0) throw new Exception("行 " + reader.getLineNumber() + ": 格式错误。正确格式：KEY = VALUE");
			String key = s.substring(0, k).trim();
			String value = s.substring(k + 1).trim();

			options.put(key, value);
		}
	}
	
	/**
	 * 取得配置中的值。若未配置，则报错
	 * @param <T>
	 * @param key
	 * @param type
	 * @return
	 */
	public <T> T get(String key, Class<T> type)
	{
		String value = options.get(key);
		if (value == null) throw new NullPointerException("配置项" + key + "未配置.");
		
		Converter converter = Converter.getConverter(type);
		Object obj = converter.convert(value);
		
		return type.cast(obj);
	}
	
	/**
	 * 取得配置中的值。若未配置，则返回默认值
	 * @param <T>
	 * @param key
	 * @param type
	 * @param defaults
	 * @return
	 */
	public <T> T get(String key, Class<T> type, T defaults)
	{
		String value = options.get(key);
		if (value == null) return defaults;
		
		Converter converter = Converter.getConverter(type);
		Object obj = converter.convert(value);
		
		return type.cast(obj);
	}
}